package org.semanticflash.rdf
{
	
	
	import flash.utils.Dictionary;
	
	import mx.rpc.IResponder;
	import mx.rpc.Responder;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	
	import org.semanticflash.rdf.io.auto.RDFAutoLoader;
	import org.semanticflash.rdf.script.RDFNode;
	import org.semanticflash.rdf.script.RDFNodeFactory;
	import org.semanticflash.rdf.values.IRDFValueHolder;
	import org.semanticflash.rdf.values.IRI;
	
	
	
	
	/**
	 * 
	 * An ultra-simple API that will serve as an indirection and simplification layer during development.
	 * Demos and high level tests are all built against this API.
	 * 
	 * The idea is to make this a central entry point into the framework.
	 * 
	 * TODO: It should have value factories, ways to fecth data, ways to write data, etc.
	 * 20% of the functionality to do 80% of the stuff...
	 * 
	 * 
	 * @author aldo.bucchi@gmail.com
	 * 
	 */	
	public class RDF
	{
		
		
		
		
		public static function getNode( value:*, responder:IResponder ):void
		{
			
			var r:Function = function( triples:Array ):void
				{
					var node:RDFNode = RDFNodeFactory
											.forProvider( triples )
												.getNode( value2IRI( value ) );
					responder.result( node );		
				}
			
			var f:Function = function( fault:* ):void
				{
					responder.fault( fault );	
				}
			
			getTriples( value, new Responder( r, f ) );
								
		}
		
		
		
		
		
		
		private static var getTriples_pendingReq:Dictionary = new Dictionary( );

		// KLUDGE
		public static function getTriples( value:*, responder:IResponder, baseURL:String=null ):void
		{
			
			var url:String = value2docURL( value ); // TODO: handle errors


			var l:RDFAutoLoader = new RDFAutoLoader( url, baseURL );
			
			
			var r:Function = function( event:ResultEvent ):void
				{
					responder.result.call( null, event.result );
					delete getTriples_pendingReq[ event.target ];
				}
			
			var f:Function = function( event:FaultEvent ):void
				{
					responder.fault.call( null, event.fault );
					delete getTriples_pendingReq[ event.target ];
				}			
			
			
			l.addEventListener( ResultEvent.RESULT, r );
			l.addEventListener( FaultEvent.FAULT, f );
			
			getTriples_pendingReq[ l ] = true;
			
			l.load( );

		}



		
		private static function value2IRI( value:* ):IRI
		{
		
			if ( value is IRDFValueHolder )
				return ( value as IRDFValueHolder ).rdfValue as IRI;

			if ( value is String )
				return IRI.instance( value );
				
			if ( value is QName )
				return IRI.instance3( value );
		
			return null;
		}



		private static function value2docURL( value:* ):String
		{

			var iri:IRI = value2IRI( value );
			
			if ( iri == null )
				return null;
			
			var str:String = iri.noFragment.stringForm;
			
			if ( str.charAt( str.length-1 ) == "#" )
				str = str.substr( 0, str.length-1 );
			
			return str;
					
		}		
		
		
		
		
	}


}